#include <string>
#include<thread>
#include<iostream>

// 单例模式是一种创建型设计模式， 让你能够保证一个类只有一个实例， 并提供一个访问该实例的全局节点。

// singleton1.cpp实现一个粗糙的单例，仅需隐藏构造函数并实现一个静态的构建方法即可。
// 相同的类在多线程环境中会出错。 多线程可能会同时调用构建方法并获取多个单例类的实例。
// singleton2.cpp中添加了线程安全的几种写法。

class Singleton{
protected:
    Singleton(const std::string value): value_(value){}

    static Singleton* singleton_;

    std::string value_;
public:
    Singleton(Singleton &other) = delete;
    void operator=(const Singleton &) = delete;
    static Singleton *GetInstance(const std::string& value);
    void SomeBusiness(){}
    std::string value() const{
        return value_;
    }
};

Singleton* Singleton::singleton_ = nullptr;

Singleton *Singleton::GetInstance(const std::string& value){
    if(singleton_ == nullptr){
        singleton_ = new Singleton(value);
    }
    return singleton_;
}

void ThreadFoo(){
    std::this_thread::sleep_for(std::chrono::microseconds(1000));
    Singleton* singleton = Singleton::GetInstance("FOo");
    std::cout << singleton->value() << "\n";
}

void ThreadBar(){
    std::this_thread::sleep_for(std::chrono::microseconds(1000));
    Singleton* singleton = Singleton::GetInstance("Bar");
    std::cout << singleton->value() << "\n";
}

int main(){
    std::cout<<"如果看到相同的值，说明单例被重用了 (正确!)\n" <<
                "如果看到不同的值，说明创建了2个单例 (错误!)\n\n" <<
                "运行结果:\n"; 
    std::thread t1(ThreadBar);
    std::thread t2(ThreadFoo);
    t1.join();
    t2.join();
    return 0;
}